﻿namespace OneWorks.Utils.Easyui.Tree
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using Newtonsoft.Json;

    /// <summary>
    /// Easyui Tree JSON 格式生成类
    /// </summary>
    public class TreeHandler
    {
        private List<Entity> _entities;

        private readonly Dictionary<Guid, List<Entity>> _childNodeDic;


        public TreeHandler()
        {
            _entities = new List<Entity>();

            _childNodeDic = new Dictionary<Guid, List<Entity>>();
        }

        /// <summary>
        /// 添加树节点
        /// </summary>
        /// <typeparam name="TSource">数据实体对象类型，需要在实体属性上标记不同Tree标签</typeparam>
        /// <param name="source">数据实体对象</param>
        /// <param name="guid">节点添加后生成唯一值</param>
        /// <param name="parent">父类节点唯一值,默认为null.</param>
        public void Inert<TSource>(TSource source, ref Guid guid, Guid? parent = null)
        {
            Entity entity = ConversionEntity(source, ref guid);

            if (parent == null) _entities.Add(entity);
            else
            {
                if (_childNodeDic.ContainsKey(parent.Value))
                {
                    _childNodeDic[parent.Value].Add(entity);
                }
                else
                {
                    _childNodeDic.Add(parent.Value, new List<Entity> { entity });
                }
            }
        }

      

        /// <summary>
        /// 根据标记的实体属性,转换为Tree实体
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <param name="source"></param>
        /// <param name="guid"></param>
        /// <returns></returns>
        private static Entity ConversionEntity<TSource>(TSource source, ref Guid guid)
        {
            guid = Guid.NewGuid();
            Entity entity = new Entity { ID = guid.ToString() };
            PropertyInfo[] propertyInfos = source.GetType().GetProperties();
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            foreach (PropertyInfo propertyInfo in propertyInfos)
            {
                foreach (TreeAttribute treeAttribute in propertyInfo.GetCustomAttributes(false).OfType<TreeAttribute>())
                {
                    switch (treeAttribute.NodeType)
                    {
                        case NodeType.Text:
                            entity.Text = (string)propertyInfo.GetValue(source, null);
                            break;
                        case NodeType.IconCls:
                            entity.IconCls = (string)propertyInfo.GetValue(source, null);
                            break;
                        case NodeType.Checked:
                            entity.Checked = (bool)propertyInfo.GetValue(source, null) ? "true" : "false";
                            break;
                        case NodeType.State:
                            entity.Checked = (bool)propertyInfo.GetValue(source, null) ? "open" : "closed";
                            break;
                        case NodeType.Attribute:
                            dictionary.Add(propertyInfo.Name, propertyInfo.GetValue(source, null));
                            break;
                    }
                }
            }
            entity.Attributes = dictionary;
            return entity;
        }

        /// <summary>
        /// 拼接数据,使数据集合生成为一个树形结构
        /// </summary>
        /// <param name="datas"></param>
        /// <returns></returns>
        private List<Entity> GetData(IEnumerable<Entity> datas)
        {
            List<Entity> result = new List<Entity>();

            foreach (Entity entity in datas)
            {
                Guid guid = Guid.Parse(entity.ID);
                if (_childNodeDic.ContainsKey(guid))
                {
                    List<Entity> tempNode = _childNodeDic[guid];
                    entity.Childrens = GetData(tempNode);
                }
                result.Add(entity);
            }
            return result;
        }

        /// <summary>
        /// 返回处理后Eayui Tree 树形结构
        /// </summary>
        /// <returns></returns>
        public string GetJson()
        {
            _entities = GetData(_entities);

            return JsonConvert.SerializeObject(
                  _entities,
                  Formatting.Indented,
                  new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
        }
    }

}
